package com.mxpio.erp.sales.policy.impl;

import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.policy.AbstractBizOrderPolicy;
import com.mxpio.erp.common.order.policy.OrderContext;
import com.mxpio.erp.common.sales.entity.SalesOrder;
import com.mxpio.erp.common.sales.entity.SalesOrderLine;
import com.mxpio.erp.common.sales.entity.ShippingNotice;
import com.mxpio.erp.common.sales.entity.ShippingNoticeLine;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpioframework.jpa.JpaUtil;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 销售订单执行策略
 * @author fangsong
 *
 */
public class DefaultShippingPolicy extends AbstractBizOrderPolicy {

	private List<OrderExcuteLineVo> orderExcuteVos;

	public DefaultShippingPolicy(List<OrderExcuteLineVo> orderExcuteVos) {
		this.orderExcuteVos = orderExcuteVos;
	}

	@Override
	public void execute(OrderContext context) {
	}

	@Override
	public OrderContext config(OrderContext context) {
		context.setOrderExcuteVos(orderExcuteVos);
		context.setNoticeClass(ShippingNotice.class);
		context.setAccessType(OrderEnums.AccessType.OUT.getCode());
		context.setPickingType(NoticeStatusEnums.NoticeType.SO_OUT.getCode());
		return context;
	}

	@Override
	public boolean beforeExecute(OrderContext context) {
		return true;
	}

	@Override
	public void afterExecute(OrderContext context) {
		Order order = context.getEntity();
		if(!(order instanceof SalesOrder)){
			return;
		}
		List<SalesOrderLine> salesOrderLineList = JpaUtil.linq(SalesOrderLine.class).equal("bizNo",order.getBizNo()).list();
		if(CollectionUtils.isEmpty(salesOrderLineList)){
			return;
		}


		String status = OrderStatusEnums.OrderStatus.FINISHED.getStatusCode();
		for(SalesOrderLine salesOrderLine:salesOrderLineList){
			List<ShippingNotice> noticeList = JpaUtil.linq(ShippingNotice.class).equal("bizOrderNo", salesOrderLine.getBizNo()).list();
			if(CollectionUtils.isNotEmpty(noticeList)){
				Set<String> noticeNoSet = noticeList.stream().map(ShippingNotice::getNoticeNo).collect(Collectors.toSet());
				List<ShippingNoticeLine> noticeLineList = JpaUtil.linq(ShippingNoticeLine.class).in("noticeNo",noticeNoSet).equal("itemCode",salesOrderLine.getItemCode()).list();
				BigDecimal planQuantity = noticeLineList.stream().map(ShippingNoticeLine::getQuantity).reduce(BigDecimal.ZERO,BigDecimal::add);
				if(planQuantity.compareTo(salesOrderLine.getQuantity())<0){
					status = OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode();
					break;
				}
			}
			else{
				status = OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode();
			}

		}
		order.setOrderStatus(status);
		order.setExecuteTime(new Date());
		JpaUtil.update(order);


	}

}
